package com.mspbots.sync.utils;

import com.fasterxml.jackson.databind.JsonNode;
import com.mspbots.sync.model.SheetsTime;
import com.mspbots.sync.model.TicketOnly;
import com.mspbots.sync.model.TimeEntry;
import com.mspbots.sync.model.WiseUser;
import org.springframework.util.ObjectUtils;
import org.springframework.util.StringUtils;

import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.ZoneOffset;
import java.time.ZonedDateTime;
import java.time.format.DateTimeFormatter;
import java.time.format.DateTimeParseException;

/**
 * com.mspbots.sync.utils.WiseResultBuildUtils
 *
 * @author Alex bob(https://github.com/vnobo)
 * @date Created by 2019/12/23
 */
public class WiseResultBuildUtils {

    public static WiseUser buildWiseUser(Integer tenant, JsonNode userNode) {
        String firstName = null;
        if (!StringUtils.isEmpty(userNode.findValue("firstName"))) {
            firstName = userNode.findValue("firstName").asText();
        }
        String lastName = null;
        if (!StringUtils.isEmpty(userNode.findValue("lastName"))) {
            lastName = userNode.findValue("lastName").asText();
        }
        String email = null;
        if (!StringUtils.isEmpty(userNode.findValue("officeEmail"))) {
            email = userNode.findValue("officeEmail").asText();
        }
        long roleId = 0;
        if (!StringUtils.isEmpty(userNode.findPath("securityRole").findValue("id"))) {
            roleId = userNode.findPath("securityRole").findValue("id").asLong();
        }
        WiseUser wiseUser = WiseUser.builder().tenantId(tenant)
                .cwUid(userNode.get("id").asLong()).tenantRoleId(roleId)
                .firstname(firstName).lastname(lastName).email(email).extend(userNode.deepCopy()).build();

        if (!StringUtils.isEmpty(userNode.findPath("lastUpdated"))) {
            wiseUser.setUpdateTime(LocalDateTime.parse(userNode.findPath("lastUpdated").asText(),
                    DateTimeFormatter.ISO_ZONED_DATE_TIME));

        }

        if (!StringUtils.isEmpty(userNode.findPath("licenseClass"))) {
            wiseUser.setLicenseClass(userNode.get("licenseClass").asText());
        }

        if (!StringUtils.isEmpty(userNode.findPath("defaultDepartment").get("id"))) {
            wiseUser.setDepartmentId(userNode.findPath("defaultDepartment").get("id").asInt());
        }
        return wiseUser;
    }

    public static TimeEntry buildTimeEntry(Integer tenant, JsonNode entriesNode) {
        String timeStart = entriesNode.get("timeStart").asText();
        LocalDateTime start;
        try {
            start = LocalDateTime.parse(timeStart, DateTimeFormatter.ISO_ZONED_DATE_TIME);
        } catch (DateTimeParseException e) {
            LocalDate tmp = LocalDate.parse(timeStart, DateTimeFormatter.ISO_LOCAL_DATE);
            start = tmp.atStartOfDay();
        }

        LocalDateTime end;
        if (StringUtils.isEmpty(entriesNode.get("timeEnd"))) {
            end = null;
        } else {
            end = LocalDateTime.parse(entriesNode.get("timeEnd").asText(), DateTimeFormatter.ISO_ZONED_DATE_TIME);
        }

        String notes = ObjectUtils.isEmpty(entriesNode.get("notes")) ? "" : entriesNode.get("notes").asText();

        return TimeEntry.builder()
                .tenantId(tenant)
                .cwUid(entriesNode.get("member").findValue("id").asLong())
                .cwTid(entriesNode.get("id").asLong())
                .beginDate(start)
                .endDate(end)
                .updatedTime(LocalDateTime.parse(entriesNode.findValue("lastUpdated").asText(),
                        DateTimeFormatter.ISO_ZONED_DATE_TIME))
                .enteredDate(LocalDateTime.parse(entriesNode.findValue("dateEntered").asText(),
                        DateTimeFormatter.ISO_ZONED_DATE_TIME))
                .actualHours(entriesNode.findValue("actualHours").asDouble())
                .description(notes)
                .extend(entriesNode.deepCopy()).build();
    }

    public static SheetsTime buildSheetsTime(Integer tenant, String key, JsonNode content) {
        SheetsTime sheetsTime = new SheetsTime();
        sheetsTime.setTenantId(tenant);
        sheetsTime.setSheetId(Long.parseLong(key));
        sheetsTime.setSheetUserId(content.findValue("user_id").asLong());
        sheetsTime.setCreatedByUserId(content.findValue("created_by_user_id").asLong());
        sheetsTime.setNotes(content.findValue("notes").asText());
        sheetsTime.setDuration(content.findValue("duration").asLong());
        sheetsTime.setStartTime(!StringUtils.isEmpty(content.findValue("start").asText()) ?
                timeCovert(content.findValue("start").asText()) : null);
        sheetsTime.setEndTime(!StringUtils.isEmpty(content.findValue("end").asText()) ?
                timeCovert(content.findValue("end").asText()) : null);
        sheetsTime.setLastModified(timeCovert(content.findValue("last_modified").asText()));
        sheetsTime.setOneDay(LocalDate.parse(content.findValue("date").asText()));
        sheetsTime.setSyncTime(LocalDateTime.now());
        sheetsTime.setExtend(content);
        sheetsTime.setOnTheClock(content.findValue("on_the_clock").asBoolean());
        return sheetsTime;
    }

    /**
     * <p>
     * TSheets data time is Date/time that represents the start time of this timesheet, in ISO 8601 format (YYYY-MM-DDThh:mm:ss±hh:mm);
     * to local utc localDateTime
     * </p>
     *
     * @param dateTimeStr TSheets date time str
     * @return local utc localDateTime
     */
    public static LocalDateTime timeCovert(String dateTimeStr) {
        return ZonedDateTime.parse(dateTimeStr, DateTimeFormatter.ISO_OFFSET_DATE_TIME)
                .withZoneSameInstant(ZoneOffset.UTC).toLocalDateTime();
    }

    public static TicketOnly buildTicketOnly(Integer tenant, JsonNode content) {
        TicketOnly ticket = TicketOnly.builder().cwId(content.get("id").asLong()).tenantId(tenant)
                .boardId(content.get("board").get("id").asInt())
                .updatedBy(content.findValue("updatedBy").asText())
                .owner(ObjectUtils.isEmpty(content.get("owner")) ? null : content.get("owner").get("id").asInt()).build();

        JsonNode companyNode = content.get("company");
        if (!org.springframework.util.ObjectUtils.isEmpty(companyNode)) {
            ticket.setCompanyId(companyNode.get("id").asInt());
            ticket.setCompanyName(companyNode.get("name").asText());
        }

        JsonNode priorityNode = content.get("priority");
        if (!org.springframework.util.ObjectUtils.isEmpty(priorityNode)) {
            ticket.setPriorityId(priorityNode.get("id").asInt());
            ticket.setPriorityName(priorityNode.get("name").asText());
        }

        JsonNode statusNode = content.get("status");
        if (!org.springframework.util.ObjectUtils.isEmpty(statusNode)) {
            ticket.setStatus(statusNode.get("name").asText());
            ticket.setStatusId(statusNode.get("id").asInt());
        }

        JsonNode contactNode = content.get("contact");
        if (!org.springframework.util.ObjectUtils.isEmpty(contactNode)) {
            ticket.setContactId(contactNode.get("id").asInt());
            ticket.setContactName(contactNode.get("name").asText());
        }

        JsonNode summaryNode = content.get("summary");
        if (!org.springframework.util.ObjectUtils.isEmpty(summaryNode)) {
            ticket.setSummary(summaryNode.asText());
        }

        JsonNode resourcesNode = content.get("resources");
        if (!org.springframework.util.ObjectUtils.isEmpty(resourcesNode)) {
            ticket.setResources(resourcesNode.asText());
        }

        JsonNode recordTypeNode = content.get("recordType");
        if (!org.springframework.util.ObjectUtils.isEmpty(recordTypeNode)) {
            ticket.setRecordType(recordTypeNode.asText());
        }

        JsonNode subBillingMethodNode = content.get("subBillingMethod");
        if (!org.springframework.util.ObjectUtils.isEmpty(subBillingMethodNode)) {
            ticket.setSubBillingMethod(subBillingMethodNode.asText());
        }

        JsonNode locationNode = content.get("location");
        if (!org.springframework.util.ObjectUtils.isEmpty(locationNode)) {
            ticket.setLocationName(locationNode.get("name").asText());
        }


        ticket.setCreatedTime(LocalDateTime.parse(content.findValue("dateEntered").asText(),
                DateTimeFormatter.ISO_ZONED_DATE_TIME));
        ticket.setUpdatedTime(LocalDateTime.parse(content.findValue("lastUpdated").asText(),
                DateTimeFormatter.ISO_ZONED_DATE_TIME));
        ticket.setExtend(content);
        return ticket;
    }
}
